package com.kedacom.emptyproject.map.widget

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.support.constraint.ConstraintLayout
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.animation.AnimationUtils
import com.kedacom.emptyproject.R
import com.kedacom.emptyproject.map.behavior.MyBottomSheetBehavior
import com.kedacom.emptyproject.util.MeshHelper
import com.kedacom.emptyproject.util.dp2px


/**
 * @author GuanHaoran
 * @description:
 * @date :2020/10/19 4:31 PM
 */
class MyBitmapMeshConstraintLayout(
    context: Context,
    attributes: AttributeSet?,
    defStyle: Int = 0
) : ConstraintLayout(context, attributes, defStyle) {


    constructor(ctx: Context, attributes: AttributeSet?) : this(
        context = ctx,
        attributes = attributes
    )

    constructor(ctx: Context) : this(context = ctx, attributes = null)

    private val mCapAnimListener: CaptureAnimListener? = null
    private var width = 0f
    private var height: Float = 0f
    private val acInterpolator = AccelerateDecelerateInterpolator()
    private var beginValueAnimator: ValueAnimator? = null
    private var endValueAnimator: ValueAnimator? = null
    private var mBitmap: Bitmap? = null
    private val mPaint = Paint()
    private var mMeshHelper: MeshHelper? = null
    private var posi = 0f

    private var isAnim = false

    private var startView: MyConstraintLayoutBehaviorView? = null
    private var behavior: MyBottomSheetBehavior<ConstraintLayout>? = null
    private var bottomTabView: MapLayerBottomTabView? = null
    private var endView: View? = null
    private var startViewLocInWindow: IntArray = intArrayOf(0, 0)
    private var endViewLocInWindow: IntArray = intArrayOf(0, 0)

    init {

        mPaint.isAntiAlias = true
        mMeshHelper = MeshHelper()
        beginValueAnimator = ValueAnimator.ofFloat(0f, 1f)
        beginValueAnimator?.duration = 450
        beginValueAnimator?.interpolator = acInterpolator
        beginValueAnimator?.addUpdateListener { animation ->
            val posi = animation.animatedValue as Float
            setPosi(posi)
            endView?.alpha = posi
            if (posi == 1f) {
                mCapAnimListener?.onCaptureAnimEnd()
                behavior?.setState(MyBottomSheetBehavior.STATE_COLLAPSED)
                isAnim = false

            }
            if (posi == 0f) {
                isAnim = true
                startView?.visibility = View.GONE
                endView?.visibility = View.VISIBLE
                endView?.isEnabled = true
                endView?.startAnimation(AnimationUtils.loadAnimation(context, R.anim.slight_shake))

            }
        }
        endValueAnimator = ValueAnimator.ofFloat(1f, 0f)
        endValueAnimator?.duration = 500
        endValueAnimator?.interpolator = acInterpolator
        endValueAnimator?.addUpdateListener { animation ->
            val posi = animation.animatedValue as Float
            setPosi(posi)

            endView?.alpha = posi
            if (posi == 0f) {
                mBitmap = null
                startView?.visibility = View.VISIBLE
                endView?.visibility = View.INVISIBLE
                endView?.isEnabled = false
                invalidate()
                mCapAnimListener?.onCaptureAnimEnd()
                isAnim = false
            }

            if (posi == 1f) {
                behavior?.setState(MyBottomSheetBehavior.STATE_MIDDLE)
                isAnim = true
            }
        }

    }

    fun isAnim() = isAnim


    private fun setBitmap(bitmap: Bitmap) {
        mBitmap = bitmap
        mMeshHelper?.setBitmapDet(bitmap.width, bitmap.height)
    }

    private fun setOffset(startX: Float, endX: Float, startY: Float, endY: Float) {
        mMeshHelper?.setOffset(startX, endX, startY, endY)
    }

    /* override fun onDraw(canvas: Canvas) {
         super.onDraw(canvas)


         if (mBitmap == null || mMeshHelper == null) return
         val mesh: FloatArray = mMeshHelper?.setPosi(posi)!!

         //        Log.d(TAG,"onDraw: mesh size:"+mesh.length);
         canvas.drawBitmapMesh(
             mBitmap, mMeshHelper?.vetWidth!!, mMeshHelper?.vetHeight!!
             , mesh, 0, null, 0, mPaint
         )

     }
 */
    override fun dispatchDraw(canvas: Canvas?) {
        super.dispatchDraw(canvas)

        if (mBitmap == null || mMeshHelper == null) return
        val mesh: FloatArray = mMeshHelper?.setPosi(posi)!!

        //        Log.d(TAG,"onDraw: mesh size:"+mesh.length);
        //        Log.d(TAG,"onDraw: mesh size:"+mesh.length);
        canvas!!.drawBitmapMesh(
            mBitmap!!,
            mMeshHelper!!.getVetWidth(),
            mMeshHelper!!.getVetHeight(),
            mesh,
            0,
            null,
            0,
            mPaint
        )
/*

         canvas?.drawRect(mMeshHelper!!.getStartX(),
             mMeshHelper!!.getEndY(),
             mMeshHelper!!.getEndX(),
             mMeshHelper!!.getEndY()+endView!!.measuredHeight,Paint().apply {
             color = Color.parseColor("#880000ff")
         })


         canvas?.drawRect(mMeshHelper!!.getStartX(),
             mMeshHelper!!.getStartY(),
             mMeshHelper!!.getStartX()+startView!!.measuredWidth,
             mMeshHelper!!.getStartY()+710,Paint().apply {
            color = Color.parseColor("#8800ff00")
        })

*/


    }

    /**
     * 应用需求,需要根据在xml描述的宽高自适应故这么写,
     *
     */
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        width = measureHanlder(1080, widthMeasureSpec).toFloat()
        height = measureHanlder(1920, heightMeasureSpec).toFloat()
        Log.d(
            "qin",
            "onMeasure width:$width  height:$height"
        )
        mMeshHelper?.init(width.toInt(), (height * 0.95f).toInt())
        if (mBitmap != null) {
            mMeshHelper?.setBitmapDet(mBitmap!!.width, mBitmap!!.height)
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    }

    private fun measureHanlder(defaultSize: Int, measureSpec: Int): Int {
        var result = defaultSize
        val specMode = MeasureSpec.getMode(measureSpec)
        val specSize = MeasureSpec.getSize(measureSpec)
        result = if (specMode == MeasureSpec.EXACTLY) {
            specSize
        } else if (specMode == MeasureSpec.AT_MOST) {
            Math.min(defaultSize, specSize)
        } else {
            defaultSize
        }
        return result
    }

    fun setPosi(posi: Float) {
        this.posi = posi
        invalidate()
    }

    interface CaptureAnimListener {
        fun onCaptureAnimEnd()
    }

    fun beginAnim() {
        if (beginValueAnimator != null) {
            isAnim = true

            beginValueAnimator!!.start()
        }
    }

    fun endAnim() {
        if (endValueAnimator != null) {
            isAnim = true

            endValueAnimator!!.start()
        }
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)

        getWindowView()


//        if (startView != null && endView != null) {
//            initViewWinLocation()
//        }

    }

    private fun getWindowView() {
        if (startView == null || endView == null) {
            for (i in 0 until childCount) {
                if (getChildAt(i).tag == "startView" && getChildAt(i) is MyCoordinatorLayoutView) {
                    for (j in 0..(getChildAt(i) as MyCoordinatorLayoutView).childCount) {

                        if ((getChildAt(i) as MyCoordinatorLayoutView).getChildAt(j) is MyConstraintLayoutBehaviorView) {
                            startView =
                                (getChildAt(i) as MyCoordinatorLayoutView).getChildAt(j) as MyConstraintLayoutBehaviorView
                            behavior = MyBottomSheetBehavior.from(startView!!)

                        }

                    }
                }

                if (getChildAt(i).tag == "endView") {
                    endView = getChildAt(i)
                }

                if (getChildAt(i).id == R.id.bottomTabView) {
                    bottomTabView = getChildAt(i) as MapLayerBottomTabView
                }
            }
        }
    }

    fun close() {
        getWindowView()
        if (mBitmap == null && behavior != null)
            setBitmap(
                toBitmap(
                    startView!!, startView?.measuredWidth!!,
                    ((parent as ConstraintLayout).height - behavior!!.getMiddleOffsetSize()
                        .toInt() - 50.dp2px())
                )
            )

        mBitmap?.apply {
            startView?.getLocationInWindow(startViewLocInWindow)
            endView?.getLocationInWindow(endViewLocInWindow)
            if (startView != null && startView != null && endView != null) {
                setOffset(
                    startViewLocInWindow[0].toFloat(),
                    (endViewLocInWindow[0] + endView!!.measuredWidth).toFloat(),
                    startViewLocInWindow[1].toFloat(),
                    (endViewLocInWindow[1] + endView!!.measuredHeight).toFloat()
                )
                beginAnim()
            }
        }
    }

    fun expanded() {
        if (mBitmap == null) {
            mBitmap = null
            startView?.visibility = View.VISIBLE
            endView?.visibility = View.INVISIBLE
            endView?.isEnabled = false
            invalidate()
            mCapAnimListener?.onCaptureAnimEnd()
            isAnim = false
            behavior?.setState(MyBottomSheetBehavior.STATE_MIDDLE)
        } else
            endAnim()
    }

    fun showAlarmNum() {
        if (endView?.visibility == View.GONE || endView?.visibility == View.INVISIBLE) {
            beginValueAnimator!!.start()

//            setPosi(1f)
//            behavior?.setState(MyBottomSheetBehavior.STATE_COLLAPSED)
        }
    }

    private fun toBitmap(view: View, bitmapW: Int, bitmapH: Int): Bitmap {
        val bitmap = Bitmap.createBitmap(bitmapW, bitmapH, Bitmap.Config.ARGB_8888)
        view.draw(Canvas(bitmap))
        return bitmap
    }
}